--
-- Author: gnar
-- Date: 2015-12-28 11:05:37
--
local WebSocket = class("WebSocket")
local httpRequest = require("app.models.network.HttpRequest")

WebSocket.CMD_CONNECT 		= 1
WebSocket.CMD_DISCONNECT 		= 2
WebSocket.CMD_SEND			= 3


function WebSocket:ctor()
	self.ws = nil

	self.sendCmds = {}

    self:onCreate()
end

function WebSocket:onCreate()
end

function WebSocket:startWithHttp(resp)

	if resp and resp.sid then
		self.sessionId = resp.sid
		self.protocol = "gbc-auth-" .. self.sessionId
		self.addr = "ws://" .. SERVER_ADDR .. "/game2"
		_connect(self)
	else
		print("WebSocket:Non resp or sid")
	end

end

function WebSocket:getSessionId()
	return self.sessionId
end

function WebSocket:_send(args)
print("WebSocket:_send")
	self:_sendCmd(WebSocket.CMD_SEND, args)
end

function WebSocket:_sendCmd(cmd, args)
	local d = {cmd = cmd, data = args}
	table.insert(self.sendCmds, d)
end

function WebSocket:onOpen(callback)
	self.openCB_ = callback
end

function WebSocket:onMessage(callback)
	self.messageCB_ = callback
end

function WebSocket:onClose(callback)
	self.closeCB_ = callback
end

function WebSocket:onError(callback)
	self.errorCB_ = callback
end

function WebSocket:on(callback)
	self.callback_ = callback
end

function WebSocket:disconnect()
	if self.ws then
		self.ws:close()
	end
end

_connect = function(self)
	print("WebSocket:_connect")
	local ws = cc.WebSocket:createByAProtocol(self.addr, self.protocol)


	ws:registerScriptHandler(handler(self, _wsOpen), cc.WEBSOCKET_OPEN)
    ws:registerScriptHandler(handler(self, _wsMessage), cc.WEBSOCKET_MESSAGE)
    ws:registerScriptHandler(handler(self, _wsClose), cc.WEBSOCKET_CLOSE)
    ws:registerScriptHandler(handler(self, _wsError), cc.WEBSOCKET_ERROR)

    self.ws = ws
end



_wsOpen = function(self)
	printInfo("WebSocket ws open")

	local scheduler = cc.Director:getInstance():getScheduler()
	local handler
	handler = scheduler:scheduleScriptFunc(function()
		--scheduler:unscheduleScriptEntry(handler)
		_operCmd(self)
	end, 0.01, false)


	--self:operCmd_()
	if self.openCB_ then
		self.openCB_()
	end
end

_wsMessage = function(self,data)
	-- printInfo("WebSocket ws message")
	if self.messageCB_ then
		self.messageCB_(data)
	end
	if self.callback_ then
		self.callback_(data)
	end
end

_wsClose = function(self)
	self.ws = nil
	self.protocol = nil
	self.sendCmds = {}
	printInfo("WebSocket ws close")
	if self.closeCB_ then
		self.closeCB_()
	end
end

_wsError = function(self,data)
	printInfo("WebSocket ws error")
	if self.errorCB_ then
		self.errorCB_(data)
	end
end

_operCmd = function(self)
	--while true do
		local cmd = self.sendCmds[1]
		if not cmd then
			return
		end

		if WebSocket.CMD_CONNECT == cmd.cmd then
			if not self.ws or cc.WEBSOCKET_STATE_CLOSED == self.ws:getReadyState() then
				if self.protocol then
					_connect(self)
				else
					httpRequest.launch(self)
				end
				return
			end
		elseif WebSocket.CMD_DISCONNECT == cmd.cmd then
			if self.ws
				and (cc.WEBSOCKET_STATE_CONNECTING == self.ws:getReadyState()
					or cc.WEBSOCKET_STATE_OPEN == self.ws:getReadyState()) then
				self.sendCmds = {}
				self:disconnect()
			end
		elseif WebSocket.CMD_SEND == cmd.cmd then
			if not self.ws then
				if self.protocol then
					_connect(self)
					printInfo("to Connect")
				else
					httpRequest.launch(self)
				end
				return
			elseif cc.WEBSOCKET_STATE_OPEN == self.ws:getReadyState() then
				_sendReal(self,cmd.data)
				table.remove(self.sendCmds, 1)
			else
				printInfo("WebSocket operCmd error:%d", self.ws:getReadyState())
				return
			end
		end
	--end
end

_sendReal = function(self,data)
	printInfo("WebSocket send real data:%s", data)
	self.ws:sendString(data)
end




return WebSocket
